package cn.com.headfree.salary.service.impl;

import cn.com.headfree.depterprela.service.IDeptErpRelaService;
import cn.com.headfree.entity.*;
import cn.com.headfree.entity.isc.User;
import cn.com.headfree.point.service.PersonYearPointDetailService;
import cn.com.headfree.point.service.RuleElementService;
import cn.com.headfree.salary.service.IPointcalculateService;
import cn.com.headfree.salary.service.IUserDataInfoService;
import cn.com.headfree.vo.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description: TODO
 * @Author wcSun
 * @Date 2021/8/12
 **/
@Service("pointcalculateService")
public class PointcalculateServiceImpl implements IPointcalculateService {

    private static final Logger LOG = LogManager.getLogger(PointcalculateServiceImpl.class);

    // 年度绩效
    @Value("${t_year_effect_info}")
    private String t_year_effect_info;
    // 学历信息
    @Value("${t_educate_info}")
    private String t_educate_info;
    // 专业技术资格
    @Value("${t_pro_tec_info}")
    private String t_pro_tec_info;
    // 技能等级信息
    @Value("${t_skill_level_info}")
    private String t_skill_level_info;
    // 专家人才称号
    @Value("${t_expert_title_info}")
    private String t_expert_title_info;
    // 学术成果
    @Value("${t_acade_achive_info}")
    private String t_acade_achive_info;
    // 专利信息
    @Value("${t_patent_info}")
    private String t_patent_info;
    // 技艺革新信息
    @Value("${t_tec_innov_info}")
    private String t_tec_innov_info;
    // 竞赛考试信息
    @Value("${t_contest_info}")
    private String t_contest_info;
    // 科技管理及创新成果
    @Value("${t_tec_man_innov}")
    private String t_tec_man_innov;
    // 个人荣誉
    @Value("${t_honor_info}")
    private String t_honor_info;
    // 員工流動
    @Value("${t_employee_mobility}")
    private String t_employee_mobility;
    // 技术标准
    @Value("${t_tec_standard_info}")
    private String t_tec_standard_info;
    // 工龄
    @Value("${t_employ_length}")
    private String t_employ_length;

    @Value("${d_value}")
    private double d_value;


    @Autowired
    private IUserDataInfoService userDataInfoService;

    @Autowired
    private RuleElementService ruleElementService;

    @Autowired
    private PersonYearPointDetailService personYearPointDetailService;

    @Autowired
    private IDeptErpRelaService deptErpRelaService;

    /**
     * 后台积分计算
     * @param creatUser
     * @param salaryInfo
     */
    public void saveSalaryPointDeatail(User creatUser,TSalaryInfo salaryInfo) throws ParseException {
        TPersonYearPointDetail personYearPointDetail = new TPersonYearPointDetail();

        String erpNo = salaryInfo.getErpNo();
        String salaryId = salaryInfo.getId();
        String ruleId = salaryInfo.getRuleId();
        int year = salaryInfo.getYear();
        boolean salary = false;

        User user = new User();
        user.setFax(erpNo);
        user.setBaseOrgId(salaryInfo.getOrgId());
        /******* 基础信息 -  ********/
        //erp编号
        personYearPointDetail.setErpNo(erpNo);
        //姓名
        personYearPointDetail.setUserName(salaryInfo.getUserName());
        //薪档调整表ID
        personYearPointDetail.setSalaryId(salaryId);
        //积分规则表ID
        personYearPointDetail.setRuleId(ruleId);
        //所属单位ID
        personYearPointDetail.setOrgId(salaryInfo.getOrgId());
        //年度
        personYearPointDetail.setYear(year);
        List<TDeptEmpRela> depts=deptErpRelaService.getDeptInfoByErpNo(personYearPointDetail.getErpNo());
        if(depts!=null&&depts.size()>0) {
            //部门id
            personYearPointDetail.setDeptId(depts.get(0).getDeptId());
            //部门名称
            personYearPointDetail.setDeptName(depts.get(0).getDeptName());
        }


        /******* 积分信息 -  ********/
        //学历积分
        List<EducateInfoVo> educateInfoList = getEducateInfoForSalary(user,erpNo,salaryId,ruleId,year,salary);
        Double yearPoint = 0.0;
        Double eduPoint = 0.0;
        if(CollectionUtils.isNotEmpty(educateInfoList)){
            for(EducateInfoVo vo : educateInfoList){
                eduPoint += vo.getPoint();
            }
            yearPoint += eduPoint;
        }
        personYearPointDetail.setEduPoint(eduPoint);

        //专业技术资格积分
        List<ProTecInfoVo> proTecInfoList = getProTecInfosForSalary(user,erpNo,salaryId,ruleId,year,salary);
        Double proTecPoint = 0.0;
        if(CollectionUtils.isNotEmpty(proTecInfoList)){
            for(ProTecInfoVo vo : proTecInfoList){
                proTecPoint += vo.getPoint();
            }
            yearPoint += proTecPoint;
        }
        personYearPointDetail.setProTecPoint(proTecPoint);

        //技能等级积分
        List<SkillLevelInfoVo> skillLevelInfoList = getSkillLevelInfoForSalary(user,erpNo,salaryId,ruleId,year,salary);
        Double skillPoint = 0.0;
        if(CollectionUtils.isNotEmpty(skillLevelInfoList)){
            for(SkillLevelInfoVo vo:skillLevelInfoList){
                skillPoint += vo.getPoint();
            }
            yearPoint += skillPoint;
        }
        personYearPointDetail.setSkillPoint(skillPoint);

        //注册执行资格积分
//        personYearPointDetail.setRegisterPoint();

        //工龄积分
        Map<String, Object> map = getEmployLengthForSalary(user, erpNo, ruleId);
        Double employPoint = 0.0;
        if(map.get("point")!=null){
            employPoint = Double.valueOf(String.valueOf(map.get("point")));
            yearPoint += employPoint;
        }
        personYearPointDetail.setEmployPoint(employPoint);

        //人才称号积分
        List<ExpertTitleVo> expertTitleList = getExpertTitleForSalary(user,erpNo,salaryId,ruleId,year,salary);
        Double expertPoint = 0.0;
        if(CollectionUtils.isNotEmpty(expertTitleList)){
            for(ExpertTitleVo vo:expertTitleList){
                expertPoint = vo.getPoint();
            }
            yearPoint += expertPoint;
        }
        personYearPointDetail.setExpertPoint(expertPoint);

        //学术成果积分
        List<AcadeAchiveVo> acadeAchiveList = getAcadeAchiveInfosForSalary(user,erpNo,salaryId,ruleId,year,salary);
        Double acadePoint = 0.0;
        if(CollectionUtils.isNotEmpty(acadeAchiveList)){
            for(AcadeAchiveVo vo:acadeAchiveList){
                acadePoint += vo.getPoint();
            }
            yearPoint += acadePoint;
        }
        personYearPointDetail.setAcadePoint(acadePoint);

        //发明专利积分
        List<PatentInfoVo> patentInfoList = getPatentInfosForSalary(user,erpNo,salaryId,ruleId,year,salary);
        Double patentPoint = 0.0;
        if(CollectionUtils.isNotEmpty(patentInfoList)){
            for(PatentInfoVo vo:patentInfoList){
                patentPoint += vo.getPoint();
            }
            yearPoint += patentPoint;
        }
        personYearPointDetail.setPatentPoint(patentPoint);

        //科技管理创新积分
        List<TecManInnovVo> tecManInnovList = getTecManInnovsForSalary(user,erpNo, salaryId,ruleId,year,salary);
        Double tecManPoint = 0.0;
        if(CollectionUtils.isNotEmpty(tecManInnovList)){
            for(TecManInnovVo vo:tecManInnovList){
                tecManPoint += vo.getPoint();
            }
            yearPoint += tecManPoint;
        }
        personYearPointDetail.setTecManPoint(tecManPoint);

        //成果推广积分
        List<TecInnovInfoVo> tecInnovInfoList = getTecInnovsInfoForSalary(user,erpNo,salaryId,ruleId,year,salary);
        Double tecInnovPoint = 0.0;
        if(CollectionUtils.isNotEmpty(tecInnovInfoList)){
            for(TecInnovInfoVo vo:tecInnovInfoList){
                tecInnovPoint += vo.getPoint();
            }
            yearPoint += tecInnovPoint;
        }
        personYearPointDetail.setTecInnovPoint(tecInnovPoint);


        //竞赛考试积分
        List<ContestInfoVo> contestInfoList = getTContestInfoForSalary(user,erpNo,salaryId,ruleId,year,salary);
        Double contestPoint = 0.0;
        if(CollectionUtils.isNotEmpty(contestInfoList)){
            for(ContestInfoVo vo:contestInfoList){
                contestPoint+=vo.getPoint();
            }
            yearPoint +=contestPoint;
        }
        personYearPointDetail.setContestPoint(contestPoint);

        //个人荣誉积分
        List<HonorDatasVo> honorDatasList = getHonorInfosForSalary(user, erpNo,salaryId,ruleId,year, salary);
        Double honorPoint = 0.0;
        if(CollectionUtils.isNotEmpty(honorDatasList)){
            for(HonorDatasVo vo:honorDatasList){
                honorPoint+=vo.getPoint();
            }
            yearPoint += honorPoint;
        }
        personYearPointDetail.setHonorPoint(honorPoint);

        //员工流动积分
        List<TEmployeeMobilityVo> employeeMobilityList = getEmployeeMobilityForSalary(user,erpNo,salaryId,ruleId,year,salary);
        Double employeeMobilityPoint = 0.0;
        if(CollectionUtils.isNotEmpty(employeeMobilityList)){
            for(TEmployeeMobilityVo vo:employeeMobilityList){
                employeeMobilityPoint+=vo.getPoint();
            }
            yearPoint += employeeMobilityPoint;
        }
        personYearPointDetail.setEmployeeMobilityPoint(employeeMobilityPoint);

        //技术标准积分
        List<TecStandardVo> tecStandardList = getTecStandardInfosForSalary(user,erpNo, salaryId,ruleId,year,salary);
        Double tecStandardPoint = 0.0;
        if(CollectionUtils.isNotEmpty(tecStandardList)){
            for(TecStandardVo vo:tecStandardList){
                tecStandardPoint+=vo.getPoint();
            }
            yearPoint += tecStandardPoint;
        }

        personYearPointDetail.setTecStandardPoint(tecStandardPoint);

        //绩效考核积分
        YearEffectVo yearEffectVo  = getYearEffectForSalary(user,erpNo, ruleId, year);
        Double yearEffectPoint = 0.0;
        if(yearEffectVo!=null){
            yearEffectPoint=yearEffectVo.getPoint();
        }
        yearPoint+=yearEffectPoint;
        personYearPointDetail.setYearEffectPoint(yearEffectPoint);
         //本年度积分
        personYearPointDetail.setYearPoint(yearPoint);
        personYearPointDetailService.saveFromSalaryInfo(personYearPointDetail,creatUser);
    }

    /**s
     * 基本情况
     *
     * @param erpNo
     * @return
     */
    public TEmpBaseInfo getTEmpBaseInfoForSalary(String erpNo) {
        TEmpBaseInfo tEmpBaseInfo = userDataInfoService.getBaseInfoByErpNo(erpNo);
        return tEmpBaseInfo;
    }

    /**
     * 学历
     */
    public List<EducateInfoVo> getEducateInfoForSalary(User user, String erpNo, String salaryId, String ruleId,
                                              int year,boolean salary) {
        // 上个年度学历对应分值
        lastEduPoint = 0.0;
        lastDreePoint = 0.0;
        // 当前申请的学历分值
        currentEduPoint = 0.0;
        currentDreePoint = 0.0;
        List<EducateInfoVo> educateInfos ;
        if (salary) {
            //已添加薪档数据
            educateInfos = userDataInfoService.getEducateInfoByErpNoInSalary(erpNo, salaryId, year,t_educate_info);
        } else {
            educateInfos = userDataInfoService.getEducateInfoByErpNo(erpNo, salaryId, year);
        }

        if (educateInfos != null && educateInfos.size() > 0) {
            educateInfos = computeEducatePoint(user, educateInfos, ruleId, erpNo, ruleId, year);
        }
        return educateInfos;
    }

    // 上个年度学历对应分值
    double lastEduPoint = 0.0;
    double lastDreePoint = 0.0;
    // 当前申请的学历分值
    double currentEduPoint = 0.0;
    double currentDreePoint = 0.0;

    /**
     * 根据学历规则计算得分
     *
     * @param ruleId
     */
    private List<EducateInfoVo> computeEducatePoint(User user, List<EducateInfoVo> educateInfos, String ruleId,
                                                    String erpNo, String salaryId, int year) {
        // 1、学历角度，分为四段中专以下（>=40）"^(([3-9]\\d)|(1([0-7]\\d)))$"、大学专科（>=30&&<20）、博士研究生（>10&&<14）、硕士（>=14&&<20）
        // 2、学位角度 学士学位（包含 4）、双学士（5）、博士学位（包含 "2")、硕士学位（包含"3"）
        // 3、按照区间
        try {

            // 前年
            int beforeYear = year - 1;
            String beforestartDate = beforeYear + "-01-01";
            String beforendDate = beforeYear + "-12-31";

            // 1.查询新增学历获取积分的配置规则
            List<TRuleElementInfo> pointList = userDataInfoService.getTRuleElementInfoByproIdAndMouId(ruleId,
                    t_educate_info, user.getBaseOrgId());
            // pointList.sort(Comparator.comparing(TRuleElementInfo::getElementLevel));//升序
            // 声明正则表达式
            final Pattern pattern = Pattern.compile("");
            // 判断系统是否已经配置过学历积分规则
            if (pointList.size() > 0) {
                // 2.查询上一年度获取的学历 ->改为   查去年以前获取的学历
                List<EducateInfoVo> beforeEducateInfos = userDataInfoService.getEducateInfoByErpNo(erpNo, salaryId,
                        beforestartDate, beforendDate);
                // 之前学历/学位积分
                if (beforeEducateInfos != null && beforeEducateInfos.size() > 0) {
                    double[] lastArr = getPointEduOrDrgeeV(beforeEducateInfos, pointList);
                    lastEduPoint = lastArr[0];
                    lastDreePoint = lastArr[1];
                    LOG.info("上一年度学历最高分：" + lastEduPoint + "," + "学位最高分：" + lastDreePoint);
                }
                double[] current = getPointEduOrDrgeeV(educateInfos, pointList);
                currentEduPoint = current[0];
                currentDreePoint = current[1];
                LOG.info("本年度学历最高分：" + currentEduPoint + "," + "学位最高分：" + currentDreePoint);

                // 将不加分的项设置为null
                educateInfos.stream().forEach(p -> {
                    p.setPoint(0.0);
                });

                if (lastDreePoint == 0.0 && lastEduPoint == 0.0) {
                    // 表示当前用户往昔没有学历信息，视为新增，此时取学历/学位最高分
                    if (currentEduPoint >= currentDreePoint) {
                        educateInfos.get(0).setPoint(currentEduPoint);
                    } else {
                        educateInfos.get(0).setPoint(currentDreePoint);
                    }
                }
                // 取差值的最高分
                if ((currentEduPoint - lastEduPoint) > (currentDreePoint - lastDreePoint)) {
                    educateInfos.get(0)
                            .setPoint((currentEduPoint - lastEduPoint) < 0 ? 0.0 : (currentEduPoint - lastEduPoint));
                } else {
                    educateInfos.get(0).setPoint(
                            (currentDreePoint - lastDreePoint) < 0 ? 0.0 : (currentDreePoint - lastDreePoint));
                }

            }

        } catch (Exception ex) {
            LOG.error("计算学历积分失败：" + ex.getMessage());
        }

        return educateInfos;
    }

    private List<EducateInfoVo> getPointEduOrDrgee(List<EducateInfoVo> beforeEducateInfos,
                                                   List<TRuleElementInfo> pointList) {
        // 对学历进行排序
        List<EducateInfoVo> beforeEducList = beforeEducateInfos.stream().filter(p -> p.getEducCode() != null)
                .collect(Collectors.toList());
        double eduMax = 0.0;
        double drgee = 0.0;
        // 算出之前学历的最高分
        if (beforeEducList != null && beforeEducList.size() > 0) {
            for (int i = 0; i < pointList.size(); i++) {
                String[] pat = pointList.get(i).getElementLevel().split(",");
                // 遍历学位集合
                for (int j = 0; j < beforeEducList.size(); j++) {
                    if (!pat[0].startsWith("&")
                            && Pattern.compile(pat[0]).matcher(beforeEducateInfos.get(0).getEducCode()).matches()) {
                        // 之前学历赋值分数
                        beforeEducList.get(j).setPoint(pointList.get(i).getPoint());

                    }
                }
            }
        }
        eduMax = beforeEducateInfos.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint()).max()
                .isPresent()
                ? beforeEducateInfos.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint())
                .max().getAsDouble()
                : 0.0;
        // 对学位进行排序
        List<EducateInfoVo> beforeDgreeList = beforeEducateInfos.stream().filter(p -> p.getDegreeCode() != null)
                .collect(Collectors.toList());
        if (beforeDgreeList != null && beforeDgreeList.size() > 0) {
            // 算出之前获取到的最高学位
            for (int i = 0; i < pointList.size(); i++) {
                String[] pat = pointList.get(i).getElementLevel().split(",");
                // 遍历学位集合
                for (int j = 0; j < beforeDgreeList.size(); j++) {
                    if (!pat[1].startsWith("&")) {
                        // 包含
                        if (beforeDgreeList.get(0).getDegreeCode().startsWith(pat[1].substring(0, 1))) {
                            // 之前学历赋值分数
                            beforeDgreeList.get(j).setPoint(pointList.get(i).getPoint());
                        }
                    }
                }
            }
        }
        drgee = beforeDgreeList.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint()).max()
                .isPresent()
                ? beforeDgreeList.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint())
                .max().getAsDouble()
                : 0.0;
        LOG.info("学历最高分：" + eduMax + "," + "学位最高分：" + drgee);
        // 对学位进行排序
        // 取学历/学位的最高分
        if (eduMax > drgee) {
            beforeEducateInfos.get(0).setPoint(eduMax);
        } else {
            beforeEducateInfos.get(0).setPoint(drgee);
        }
        return beforeEducateInfos;
    }

    /**
     * @param beforeEducateInfos
     * @param pointList
     * @return
     */
    private double[] getPointEduOrDrgeeV(List<EducateInfoVo> beforeEducateInfos, List<TRuleElementInfo> pointList) {
        // 对学历进行排序
        List<EducateInfoVo> beforeEducList = beforeEducateInfos.stream().filter(p -> p.getEducCode() != null)
                .collect(Collectors.toList());
        double[] pointArr = new double[2];
        double eduMax = 0.0;
        double drgee = 0.0;
        // 算出之前学历的最高分
        if (beforeEducList != null && beforeEducList.size() > 0) {
            for (int i = 0; i < pointList.size(); i++) {
                String[] pat = pointList.get(i).getElementLevel().split(",");
                // 遍历学位集合
                for (int j = 0; j < beforeEducList.size(); j++) {
                    if (!pat[0].startsWith("&")
                            && Pattern.compile(pat[0]).matcher(beforeEducateInfos.get(0).getEducCode()).matches()) {
                        // 之前学历赋值分数
                        beforeEducList.get(j).setPoint(pointList.get(i).getPoint());

                    }
                }
            }
        }
        eduMax = beforeEducateInfos.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint()).max()
                .isPresent()
                ? beforeEducateInfos.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint())
                .max().getAsDouble()
                : 0.0;
        // 对学位进行排序
        List<EducateInfoVo> beforeDgreeList = beforeEducateInfos.stream().filter(p -> p.getDegreeCode() != null)
                .collect(Collectors.toList());
        beforeDgreeList.stream().forEach(tmp -> tmp.setPoint(null));
        if (beforeDgreeList != null && beforeDgreeList.size() > 0) {
            // 算出之前获取到的最高学位
            for (int i = 0; i < pointList.size(); i++) {
                String[] pat = pointList.get(i).getElementLevel().split(",");
                // 遍历学位集合
                for (int j = 0; j < beforeDgreeList.size(); j++) {
                    if (!pat[1].startsWith("&")) {
                        // 包含
                        if (beforeDgreeList.get(0).getDegreeCode().startsWith(pat[1].substring(0, 1))) {
                            // 之前学历赋值分数
                            beforeDgreeList.get(j).setPoint(pointList.get(i).getPoint());
                        }
                    }
                }
            }
        }
        drgee = beforeDgreeList.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint()).max()
                .isPresent()
                ? beforeDgreeList.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint())
                .max().getAsDouble()
                : 0.0;
        pointArr[0] = eduMax;
        pointArr[1] = drgee;
        LOG.info("学历最高分：" + eduMax + "," + "学位最高分：" + drgee);
        // 对学位进行排序
        // 取学历/学位的最高分
        if (eduMax > drgee) {
            beforeEducateInfos.get(0).setPoint(eduMax);
        } else {
            beforeEducateInfos.get(0).setPoint(drgee);
        }
        return pointArr;
    }

    /**
     * 专业技术资格
     */
    public List<ProTecInfoVo> getProTecInfosForSalary(User user, String erpNo, String salaryId, String ruleId, int year ,boolean salary) {
        // 专业技术资格
        List<ProTecInfoVo> proTecInfos ;
        if (salary) {
            //已添加薪档数据
            proTecInfos = userDataInfoService.getProTecInfoByErpNoInSalary(erpNo, salaryId, t_pro_tec_info, ruleId, year, user.getBaseOrgId(),t_pro_tec_info);
        } else {
            proTecInfos = userDataInfoService.getProTecInfoByErpNo(erpNo, salaryId, t_pro_tec_info, ruleId, year, user.getBaseOrgId());
        }

        if (proTecInfos != null && proTecInfos.size() > 0) {
            culProTecPointInfo(user, proTecInfos, erpNo, salaryId, ruleId, year);
            // 判断技能等级,当前年度技能等级
            List<SkillLevelInfoVo> skillLevelInfos = userDataInfoService.getSkillLevelInfoByErpNo(erpNo, salaryId,
                    t_skill_level_info, ruleId, year, user.getBaseOrgId());
            if (skillLevelInfos != null && skillLevelInfos.size() > 0) {
                culSkillPointInfo(user, skillLevelInfos, erpNo, salaryId, ruleId, year);

                // 判断只取其中做高分
                // 技能等级最大值
                double s_max = skillLevelInfos.stream().filter(p -> p.getPoint() != null)
                        .mapToDouble(s -> s.getPoint()).max().isPresent()
                        ? skillLevelInfos.stream().filter(p -> p.getPoint() != null)
                        .mapToDouble(s -> s.getPoint()).max().getAsDouble()
                        : 0.0;

                // 专业技术资格最大值
                double p_max = proTecInfos.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint())
                        .max().isPresent()
                        ? proTecInfos.stream().filter(p -> p.getPoint() != null)
                        .mapToDouble(s -> s.getPoint()).max().getAsDouble()
                        : 0.0;
                ;
                // 如果技术等级取得分最高，专业技术资格不重复加分
                if (s_max > p_max) {
                    proTecInfos.stream().forEach(l -> {
                        l.setPoint(0.0);
                    });
                }
            }
        }
        return proTecInfos;
    }

    /**
     * 计算专业技术资格积分
     *
     * @param proTecInfos
     * @param salaryId
     * @param ruleId
     * @return
     */
    private List<ProTecInfoVo> culProTecPointInfo(User user, List<ProTecInfoVo> proTecInfos, String erpNo,
                                                  String salaryId, String ruleId, int year) {
        // 声明返回结果
        List<ProTecInfoVo> resultList = null;
        try {
            // 前年
            int beforeYear = year - 1;
            String beforestartDate = beforeYear + "-01-01";
            String beforendDate = beforeYear + "-12-31";

            // 查询历史专业技术资格
            List<ProTecInfoVo> lastProTecList = userDataInfoService.getProTecInfoByErpNo(erpNo, salaryId,
                    t_pro_tec_info, ruleId, year + "-01-01", beforendDate, user.getBaseOrgId());

            // 查询历史技能等级
            List<SkillLevelInfoVo> lastSkillList = userDataInfoService.getSkillLevelInfoByErpNo(erpNo, salaryId,
                    t_skill_level_info, ruleId, year + "-01-01", beforendDate, user.getBaseOrgId());

            proTecInfos.stream().forEach(p -> {
                //逻辑由判断之前专业改为判断所有专业 根据积分倒叙
                List<ProTecInfoVo> list = lastProTecList.stream().sorted(Comparator.comparing(ProTecInfoVo::getPoint).reversed()).collect(Collectors.toList());

                if (list != null && list.size() > 0) {
                    // 去年取得
                    double c = p.getPoint();
                    // 之前取得 最高分
                    double lc = list.get(0).getPoint();
                    if (c > lc) {
                        //判断之前有没有同级的技能等级(获取分数相同的技能等级)
                        List<SkillLevelInfoVo> skillLevelList = lastSkillList.stream().filter(skillLevelInfoVo -> skillLevelInfoVo.getPoint()==c).collect(Collectors.toList());
                        if(CollectionUtils.isNotEmpty(skillLevelList)){
                            //对于同时取得中级及以上同级专业技术资格和等级的 ，可增加0.5分（例如：原为中级职称，本年度取得技师，增加0.5分）
                            p.setPoint(0.5);
                        }else{
                            p.setPoint((c - lc));
                        }
                    }
                    else{
                        p.setPoint(0.0);
                    }
                }
            });
            // 对积分处理后，进行排序
            resultList = proTecInfos.stream().filter(p -> p.getPoint() != null)
                    .sorted(Comparator.comparing(ProTecInfoVo::getPoint).reversed()).collect(Collectors.toList());
            // 清空其余项
            double point = resultList.get(0).getPoint();
            resultList.stream().forEach(p -> {
                p.setPoint(0.0);
            });
            // 在从新赋值
            resultList.get(0).setPoint(point);

        } catch (Exception ex) {
            LOG.error("计算专业技术资格得分失败:" + ex.getMessage());
        }
        return resultList;
    }

    /**
     * 技能等级
     */
    public List<SkillLevelInfoVo> getSkillLevelInfoForSalary(User user, String erpNo, String salaryId, String ruleId, int year,boolean salary) {
        List<SkillLevelInfoVo> skillLevelInfos ;
        if (salary) {
            //已添加薪档数据
            skillLevelInfos = userDataInfoService.getSkillLevelInfoByErpNoInSalary(erpNo, salaryId, t_skill_level_info, ruleId, year, user.getBaseOrgId(),t_skill_level_info);
        } else {
            skillLevelInfos = userDataInfoService.getSkillLevelInfoByErpNo(erpNo, salaryId, t_skill_level_info, ruleId, year, user.getBaseOrgId());
        }

        if (skillLevelInfos != null && skillLevelInfos.size() > 0) {
            culSkillPointInfo(user, skillLevelInfos, erpNo, salaryId, ruleId, year);
            // 判断专业技术等级
            List<ProTecInfoVo> proTecInfos ;
            if (salary) {
                //已添加薪档数据
                proTecInfos = userDataInfoService.getProTecInfoByErpNoInSalary(erpNo, salaryId, t_pro_tec_info, ruleId, year, user.getBaseOrgId(),t_pro_tec_info);
            }else {
                proTecInfos = userDataInfoService.getProTecInfoByErpNo(erpNo, salaryId, t_pro_tec_info, ruleId, year, user.getBaseOrgId());
            }

            if (proTecInfos != null && proTecInfos.size() > 0) {
                culProTecPointInfo(user, proTecInfos, erpNo, salaryId, ruleId, year);
            }
            // 判断只取其中做高分
            // 技能等级最大值
            double s_max = skillLevelInfos.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint())
                    .max().isPresent()
                    ? skillLevelInfos.stream().filter(p -> p.getPoint() != null)
                    .mapToDouble(s -> s.getPoint()).max().getAsDouble()
                    : 0.0;
            // 专业技术资格最大值
            double p_max = proTecInfos.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint())
                    .max().isPresent()
                    ? proTecInfos.stream().filter(p -> p.getPoint() != null).mapToDouble(s -> s.getPoint())
                    .max().getAsDouble()
                    : 0.0;
            // 如果专业技术取得分最高，技术等级资格不重复加分
            if (s_max <= p_max) {
                skillLevelInfos.stream().forEach(l -> {
                    l.setPoint(0.0);
                });
            }

        }
        return skillLevelInfos;
    }

    /**
     * 计算技能等级积分
     *
     * @param skillInfos
     * @param salaryId
     * @param ruleId
     * @return
     */
    private List<SkillLevelInfoVo> culSkillPointInfo(User user, List<SkillLevelInfoVo> skillInfos, String erpNo,
                                                     String salaryId, String ruleId, int year) {
        // 声明返回结果
        List<SkillLevelInfoVo> resultList = null;
        try {

            // 前年
            int beforeYear = year - 1;
            String beforestartDate = beforeYear + "-01-01";
            String beforendDate = beforeYear + "-12-31";
            // 查询历史技能等级
            List<SkillLevelInfoVo> lastSkillList = userDataInfoService.getSkillLevelInfoByErpNo(erpNo, salaryId,
                    t_skill_level_info, ruleId, year + "-01-01", beforendDate, user.getBaseOrgId());


            // 查询历史专业技术资格
            List<ProTecInfoVo> lastProTecList = userDataInfoService.getProTecInfoByErpNo(erpNo, salaryId,
                    t_pro_tec_info, ruleId, year + "-01-01", beforendDate, user.getBaseOrgId());

            skillInfos.stream().forEach(p -> {
                // 判断当前专业的之前的专业 改为判断所有专业 根据积分倒叙
                List<SkillLevelInfoVo> list = lastSkillList.stream().sorted(Comparator.comparing(SkillLevelInfoVo::getPoint).reversed()).collect(Collectors.toList());

                if (list != null && list.size() > 0) {
                    // 去年取得
                    double c = p.getPoint();
                    // 前年取得
                    double lc = list.get(0).getPoint();
                    if (c > lc){
                        //判断之前有没有同级的专业技术资格(获取分数相同的专业技术资格)
                        List<ProTecInfoVo> protecList = lastProTecList.stream().filter(proTecInfoVo -> proTecInfoVo.getPoint()==c).collect(Collectors.toList());
                        if(CollectionUtils.isNotEmpty(protecList)) {
                            //对于同时取得中级及以上同级专业技术资格和等级的 ，可增加0.5分（例如：原为中级职称，本年度取得技师，增加0.5分）
                            p.setPoint(0.5);
                        }else{
                            p.setPoint((c - lc));
                        }
                    }
                    else {
                        p.setPoint(0.0);
                    }
                }
//				else {
//					// 新取得专业技术资格
//					p.setPoint(d_value);
//				}
            });
            // 对积分处理后，进行排序
            resultList = skillInfos.stream().filter(p -> p.getPoint() != null)
                    .sorted(Comparator.comparing(SkillLevelInfoVo::getPoint).reversed()).collect(Collectors.toList());
            // 清空其余项
            double point = resultList.get(0).getPoint();
            resultList.stream().forEach(p -> {
                p.setPoint(0.0);
            });
            // 在从新赋值
            resultList.get(0).setPoint(point);

        } catch (Exception ex) {
            LOG.error("计算专业技术资格得分失败:" + ex.getMessage());
        }
        return resultList;
    }

    /**
     * 工龄
     */
    public Map<String, Object> getEmployLengthForSalary(User user, String erpNo, String ruleId) {
        TEmpBaseInfo tEmpBaseInfo = userDataInfoService.getBaseInfoByErpNo(erpNo);
        Date jobDate = null;
        if (tEmpBaseInfo != null) {
            jobDate = tEmpBaseInfo.getJobDate();
        }
        Map<String, Object> map = new HashMap<>();
        Calendar can = Calendar.getInstance();
        int currentYear = Integer.valueOf(can.get(Calendar.YEAR));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        int employLength = 0;
        if (jobDate != null) {
            int date = Integer.valueOf(sdf.format(jobDate));
            employLength = currentYear - date + 1;
        }
        map.put("jobDate", jobDate);
        map.put("employLength", employLength);
        // 查询工龄分数
        List<TRuleElementInfo> ruleElementInfos = ruleElementService.getRuleElementInfoByRuleIdAndMouldId(ruleId,
                t_employ_length, user.getBaseOrgId());
        if (ruleElementInfos != null && ruleElementInfos.size() > 0) {
            map.put("point", ruleElementInfos.get(0).getPoint());
        } else {
            map.put("point", null);
        }
        return map;
    }

    /**
     * 专家人才称号
     */
    public List<ExpertTitleVo> getExpertTitleForSalary(User user, String erpNo, String salaryId, String ruleId,
                                              int year,boolean salary) {
            // 查询近5年内所获所有人才称号
            List<ExpertTitleVo> experts = userDataInfoService.getFiveYearExpertTitleInfoByErpNo(erpNo, salaryId,
                    t_expert_title_info, ruleId, year, user.getBaseOrgId());
            Double point = 0.0;
            if (experts != null && experts.size() > 0) {
                for (ExpertTitleVo vo : experts) {
                    if (vo.getPoint() != null) {
                        point = vo.getPoint();
                        break;
                    }
                }
            }
            // 查询上一年度所获人才称号
            List<ExpertTitleVo> expertTitleInfos ;
            if (salary) {
                //已添加薪档数据
                expertTitleInfos = userDataInfoService.getExpertTitleInfoByErpNoInSalary(erpNo, salaryId, t_expert_title_info, ruleId, year, user.getBaseOrgId(),t_expert_title_info);
            }else {
                expertTitleInfos = userDataInfoService.getExpertTitleInfoByErpNo(erpNo, salaryId, t_expert_title_info, ruleId, year, user.getBaseOrgId());
            }
            if (expertTitleInfos != null && expertTitleInfos.size() > 0) {
                // 过滤掉分数为null的
                List<ExpertTitleVo> list = expertTitleInfos.stream().filter(p -> (p.getPoint() != null))
                        .collect(Collectors.toList());
                // 同一年度同时获得多项人才称号，只取最高分,sql中已按分排序
                for (int i = 0; i < list.size(); i++) {
                    if (i > 0) {
                        list.get(i).setPoint(0.0);
                    } else {
                        //如果是级别是其他，不算积分
                        if("08".equals(list.get(i).getLevelName())){
                            list.get(i).setPoint(0.0);
                        }else{
                            Double validPoint = list.get(i).getPoint();
                            if (validPoint != null && validPoint > point) {
                                validPoint = validPoint - point;// 获得分差
                                list.get(i).setPoint(validPoint);
                            } else {
                                list.get(i).setPoint(0.0);
                            }
                        }

                    }
                }
            }
        return expertTitleInfos;
    }

    /**
     * 学术成果
     */
    public List<AcadeAchiveVo> getAcadeAchiveInfosForSalary(User user, String erpNo, String salaryId, String ruleId, int year,boolean salary) {
        List<AcadeAchiveVo> acadeAchiveVos ;
        if (salary) {
            //已添加薪档数据
            acadeAchiveVos = userDataInfoService.getAcadeAchiveInfoByErpNoInSalary(erpNo, salaryId, t_acade_achive_info, ruleId, year, user.getBaseOrgId(),t_acade_achive_info);
        } else {
            acadeAchiveVos = userDataInfoService.getAcadeAchiveInfoByErpNo(erpNo, salaryId, t_acade_achive_info, ruleId, year, user.getBaseOrgId());
        }

        if (acadeAchiveVos != null && acadeAchiveVos.size() > 0) {
            for (AcadeAchiveVo vo : acadeAchiveVos) {
                // 主编、独立撰写人、主要撰写人、第一作者、第一撰写人等要赋全部分值，其他作者赋一半分值
                if (!("01,03,04,05,07".contains(vo.getRole()))) {
                    vo.setPoint(vo.getPoint() / 2);
                }
            }
        }
        return acadeAchiveVos;
    }

    /**
     * 发明专利
     */
    public List<PatentInfoVo> getPatentInfosForSalary(User user, String erpNo, String salaryId, String ruleId, int year,boolean salary) {
        List<PatentInfoVo> patentInfos ;
        if (salary) {
            //已添加薪档数据
            patentInfos = userDataInfoService.getPatentInfoByErpNoInSalary(erpNo, salaryId, t_patent_info,ruleId, year, user.getBaseOrgId(),t_patent_info);
        }else {
            patentInfos = userDataInfoService.getPatentInfoByErpNo(erpNo, salaryId, t_patent_info,ruleId, year, user.getBaseOrgId());
        }

        if (patentInfos != null && patentInfos.size() > 0) {
            for (PatentInfoVo vo : patentInfos) {
                String sort = "";
                if (vo.getRank() != null && vo.getRank() != 0) {
                    sort = vo.getRank() + "";
                    if (vo.getTotal() != 0) {
                        sort = sort + "/" + vo.getTotal();
                    }
                }
                vo.setSort(sort);
                vo.setInventor(user.getName());
                if (vo.getRank() > 1) {
                    if (vo.getPoint() != null) {
                        vo.setPoint(vo.getPoint() / 2);
                    }
                }
            }
        }
        return patentInfos;
    }

    /**
     * 科技管理创新
     */
    public List<TecManInnovVo> getTecManInnovsForSalary(User user, String erpNo, String salaryId, String ruleId, int year,boolean salary) {
        List<TecManInnovVo> tecManInnovVos ;
        if (salary) {
            //已添加薪档数据
            tecManInnovVos = userDataInfoService.getTecManInnovByErpNoInSalary(erpNo, salaryId, t_tec_man_innov, ruleId, year, user.getBaseOrgId(),t_tec_man_innov);
        }else {
            tecManInnovVos = userDataInfoService.getTecManInnovByErpNo(erpNo, salaryId, t_tec_man_innov, ruleId, year, user.getBaseOrgId());
        }
        if (tecManInnovVos != null && tecManInnovVos.size() > 0) {
            for (TecManInnovVo vo : tecManInnovVos) {
                String sort = "";
                if (vo.getRank() != null && vo.getRank() != 0) {
                    sort = vo.getRank() + "";
                    if (vo.getTotal() != 0) {
                        sort = sort + "/" + vo.getTotal();
                    }
                }
                vo.setSort(sort);
                // 计算分值
                if (vo.getRank() > 1) {
                    vo.setPoint(vo.getPoint() / 2);
                }
            }
            List<String> list = tecManInnovVos.stream()
                    .collect(Collectors.groupingBy(vo -> vo.getAchiName(), Collectors.counting())).entrySet()
                    .stream().filter(entry -> entry.getValue() > 1).map(entry -> entry.getKey())
                    .collect(Collectors.toList());
            if (list.size() > 0) {
                for (String achiName : list) {
                    int count = 0;
                    List<Double> data = new ArrayList<Double>();
                    for (TecManInnovVo vo : tecManInnovVos) {
                        if (achiName.equals(vo.getAchiName())) {
                            data.add(vo.getPoint());
                        }
                    }
                    double maxPoint = Collections.max(data);
                    for (TecManInnovVo vo : tecManInnovVos) {
                        if (achiName.equals(vo.getAchiName())) {
                            if (maxPoint != vo.getPoint()) {
                                vo.setPoint(0.0);
                            } else {
                                count++;
                                if (count > 1) {
                                    vo.setPoint(0.0);
                                }
                            }
                        }
                    }
                }
            }
        }
        return tecManInnovVos;
    }

    /**
     * 技艺革新
     */
    public List<TecInnovInfoVo> getTecInnovsInfoForSalary(User user, String erpNo, String salaryId, String ruleId, int year,boolean salary) {
        List<TecInnovInfoVo> tecInnovInfoVos ;
        if (salary) {
            //已添加薪档数据
            tecInnovInfoVos = userDataInfoService.getTecInnovInfoByErpNoInSalary(erpNo, salaryId, t_tec_innov_info, ruleId, year, user.getBaseOrgId(),t_tec_innov_info);
        }else {
            tecInnovInfoVos = userDataInfoService.getTecInnovInfoByErpNo(erpNo, salaryId, t_tec_innov_info, ruleId, year, user.getBaseOrgId());
        }
        if (tecInnovInfoVos != null && tecInnovInfoVos.size() > 0) {
            for (TecInnovInfoVo vo : tecInnovInfoVos) {
                String sort = "";
                if (vo.getRank() != null && vo.getRank() != 0) {
                    sort = vo.getRank() + "";
                    if (vo.getTotal() != 0) {
                        sort = sort + "/" + vo.getTotal();
                    }
                }
                vo.setSort(sort);
                if(vo.getRank()>1){
                    vo.setPoint(vo.getPoint() / 2);
                }
            }
        }
        /**   同一成果名称 多个奖项，只取最高分 */
        List<String> list = tecInnovInfoVos.stream()
                .collect(Collectors.groupingBy(vo -> vo.getAchiName(), Collectors.counting())).entrySet()
                .stream().filter(entry -> entry.getValue() > 1).map(entry -> entry.getKey())
                .collect(Collectors.toList());
        if (list.size() > 0) {
            for (String achiName : list) {
                int count = 0;
                List<Double> data = new ArrayList<Double>();
                for (TecInnovInfoVo vo : tecInnovInfoVos) {
                    if (achiName.equals(vo.getAchiName())) {
                        data.add(vo.getPoint());
                    }
                }
                double maxPoint = Collections.max(data);
                for (TecInnovInfoVo vo : tecInnovInfoVos) {
                    if (achiName.equals(vo.getAchiName())) {
                        if (maxPoint != vo.getPoint()) {
                            vo.setPoint(0.0);
                        }
                    }
                }
            }
        }
        return tecInnovInfoVos;
    }

    /**
     * 专业竞赛考试
     */
    public List<ContestInfoVo> getTContestInfoForSalary(User user, String erpNo, String salaryId, String ruleId, int year,boolean salary) {
        // 竞赛考试
        List<ContestInfoVo> tContestInfos ;
        if (salary) {
            //已添加薪档数据
            tContestInfos = userDataInfoService.getContestInfoByErpNoInSalary(erpNo, salaryId, t_contest_info, ruleId, year, user.getBaseOrgId(),t_contest_info);
        }else {
            tContestInfos = userDataInfoService.getContestInfoByErpNo(erpNo, salaryId,
                    t_contest_info, ruleId, year, user.getBaseOrgId());
        }

        if (tContestInfos != null && tContestInfos.size() > 0) {
            List<Double> list = new ArrayList<Double>();
            for (ContestInfoVo vo : tContestInfos) {
                list.add(vo.getPoint());
            }
            double maxPoint = Collections.max(list);
            int count = 0;
            for (ContestInfoVo vo : tContestInfos) {
                if (maxPoint != vo.getPoint()) {
                    vo.setPoint(0.0);
                } else {
                    count++;
                    if (count > 1) {
                        vo.setPoint(0.0);
                    }
                }
            }
        }
        return tContestInfos;
    }

    /**
     * 个人荣誉
     */
    public List<HonorDatasVo> getHonorInfosForSalary(User user, String erpNo, String salaryId, String ruleId, int year,boolean salary) {
        List<HonorDatasVo> honorDatasVos ;
        if (salary) {
            //已添加薪档数据
            honorDatasVos = userDataInfoService.getHonnorInfoByErpNoInSalary(erpNo, salaryId, t_honor_info, ruleId, year, user.getBaseOrgId(),t_honor_info);
        } else {
            honorDatasVos = userDataInfoService.getHonnorInfoByErpNo(erpNo, salaryId, t_honor_info, ruleId, year, user.getBaseOrgId());
        }
        if (honorDatasVos != null && honorDatasVos.size() > 0) {
            List<Double> list = new ArrayList<Double>();
            for (HonorDatasVo vo : honorDatasVos) {
                list.add(vo.getPoint());
            }
            double maxPoint = Collections.max(list);
            int count = 0;
            for (HonorDatasVo vo : honorDatasVos) {
                //如果是其他，不算积分,或者宣城地市及以下不算积分
                if (maxPoint != vo.getPoint() ||"6".equals(vo.getHonorLevel()) || ("10333706".equals(user.getBaseOrgId()) && ("3".equals(vo.getHonorLevel()) || "4".equals(vo.getHonorLevel())|| "5".equals(vo.getHonorLevel())))) {
                    vo.setPoint(0.0);
                } else {
                    count++;
                    if (count > 1) {
                        vo.setPoint(0.0);
                    }
                }
            }
        }
        return honorDatasVos;
    }
    /**
     * 技术标准
     */
    public List<TecStandardVo> getTecStandardInfosForSalary(User user, String erpNo, String salaryId, String ruleId, int year,boolean salary) {
        List<TecStandardVo> tecStandardInfoVos ;
        if (salary) {
            //已添加薪档数据
            tecStandardInfoVos = userDataInfoService.getTecStandardInfoByErpNoInSalary(erpNo, salaryId, t_tec_standard_info, ruleId, year, user.getBaseOrgId(),t_tec_standard_info);
        } else {
            tecStandardInfoVos = userDataInfoService.getTecStandardInfoByErpNo(erpNo, salaryId, t_tec_standard_info, ruleId, year, user.getBaseOrgId());
        }
        if (tecStandardInfoVos != null && tecStandardInfoVos.size() > 0) {
            for (TecStandardVo vo : tecStandardInfoVos) {
                // 主编要赋全部分值，其他作者赋一半分值
                if (!("1".contains(vo.getRole()))) {
                    vo.setPoint(vo.getPoint() / 2);
                }
            }
        }
        return tecStandardInfoVos;
    }
    /**
     * 年度绩效
     */
    public YearEffectVo getYearEffectForSalary(User user, String erpNo, String ruleId, int year) {
        List<YearEffectVo> yearEffectVos = userDataInfoService.getYearEffectByErpNo(erpNo, t_year_effect_info,
                ruleId, year, user.getBaseOrgId());
        if (yearEffectVos != null && yearEffectVos.size() > 0) {
            return yearEffectVos.get(0);
        }
        return null;
    }

    /**
     * 员工流动
     */
    public List<TEmployeeMobilityVo> getEmployeeMobilityForSalary(User user, String erpNo, String salaryId,
                                                   String ruleId, int year,boolean salary) throws ParseException {

        List<TEmployeeMobilityVo> employeeMobilities = null;
        if (salary){
            //已添加薪档数据
            employeeMobilities = userDataInfoService.getEmployeeMobilityByErpNoInSalary(erpNo, salaryId, t_employee_mobility, ruleId, year, user.getBaseOrgId(),t_employee_mobility);
        }else{
            employeeMobilities = userDataInfoService.getEmployeeMobilityByErpNo(erpNo, salaryId, t_employee_mobility, ruleId, year, user.getBaseOrgId());
        }

        List<TEmployeeMobilityVo> newEmployeeMobilities = new ArrayList<TEmployeeMobilityVo>();
        if (employeeMobilities != null && employeeMobilities.size() > 0) {
            // List<Double> list = new ArrayList<Double>();
            for (int i = 0; i < employeeMobilities.size(); i++) {
                TEmployeeMobilityVo vo = employeeMobilities.get(i);
                Date beginTime = vo.getBeginTime();
                Date endTime = vo.getEndTime();
                if ((beginTime.getYear() + 1900) <= year) {
                    if ((beginTime.getYear() + 1900) < year) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                        String beginTimeStr = year + "-01-01";
                        beginTime = sdf.parse(beginTimeStr);

                    }
                    // 去年
                    if ((endTime.getYear() + 1900) > year) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                        String endTimeStr = year + "-12-31";
                        endTime = sdf.parse(endTimeStr);
                    }
                    long daysBetween = (endTime.getTime() - beginTime.getTime()) / (60 * 60 * 24 * 1000);
                    if (daysBetween >= 0) {
                        // 计算服务了几个月
                        long monthCounts = (long) round(daysBetween / 30.0, 0);
                        System.out.println("..............................服务月数:i=" + monthCounts);
                        LOG.info("..............................服务月数:i=" + monthCounts);
                        vo.setPoint(round((monthCounts / 12.0) * vo.getPoint(), 2));
                        LOG.info("..............................员工流动分数=" + vo.getPoint());
                        newEmployeeMobilities.add(vo);
                    }
                }
            }
        }
        employeeMobilities = newEmployeeMobilities;
        return employeeMobilities;
    }

    /**
     * 提供精确的小数位四舍五入处理。
     *
     * @param v     需要四舍五入的数字
     *
     * @param scale 小数点后保留几位
     *
     * @return 四舍五入后的结果
     *
     */
    public static double round(double v, int scale) {

        if (scale < 0) {

            throw new IllegalArgumentException("The scale must be a positive integer or zero");

        }

        BigDecimal b = new BigDecimal(Double.toString(v));

        BigDecimal one = new BigDecimal("1");

        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();

    }

}
